package com.me.study.concurrent.threadLocal;

import com.me.common.util.SleepUtil;

/**
 * 测试 ThreadLocal 内存泄露：
 *
 * @author ME
 * @date 2021/6/22
 */
public class TestThreadLocalMemoryLeak {

    /**
     * 配置 VM options：
     * -Xms15m -Xmx15m -XX:+PrintGCDetails -XX:SurvivorRatio=3 -XX:+PrintGCTimeStamps
     * -XX:NewRatio=2 -XX:+UseSerialGC
     */
    public static void main(String[] args) {
        // 普通 50M 的变量，释放强引用之后能回收
        _50MB general;
        // ThreadLocal 变量，释放强引用后，还被线程内部的 ThreadLocalMap 持有，无法回收
        ThreadLocal<_50MB> local = new ThreadLocal<>();
        SleepUtil.seconds(5);
        general = new _50MB();
        local.set(new _50MB());
        SleepUtil.seconds(2);
        general = null;
        local = null;

        System.gc();
        SleepUtil.seconds(60);
    }

    public static class _50MB {
        private byte[] _50m = new byte[1024 * 1024 * 50];
    }
}
